//deliver management

var client = require('../common/redisClient');
var widget = require('./widgetManagement');
var redisKey = require('./redisKeyManagement');
var changeLog = require('./changeLog');

//return a diff array between a and b
function getDiff(a,b){
	var diff = [];
	for(var opt in b){
		if(b[opt]!=a[opt]){
			diff.push({	//oldValue and newValue
				column : opt,
				oldValue : a[opt] ,
				newValue : b[opt]
			});	
		}
	}
	return diff;
}

// 获取如2015-02-01这样的日期格式
function getDateString(d){
	var year = d.getFullYear()
		,month = d.getMonth()+1
		,date = d.getDate()
		;
	return year+'-'+(month<10?'0'+month:month)+'-'+(date<10?'0'+date:date);
}

// 获取昨天的CNZZ数据
function getCnzzData (setting,callback){

	var http = require('http')
		,cnzzid = setting.cnzzid
		,yesterday_str = getDateString(new Date(Date.now()-1000*3600*24))
		;
	var options = {
		hostname: 'tongji.cnzz.com',
		port: 80,
		// path: '/main.php?c=site&a=overview&ajax=module%3Dsummary&siteid='+cnzzid+'&_='+Date.now(),
		path:'/main.php?c=flow&a=trend&ajax=module%3Dsummary%7Cmodule%3DfluxList_currentPage%3D1_pageType%3D30&siteid='+cnzzid+'&st='+yesterday_str+'&et='+yesterday_str+'&_='+Date.now(),
		method: 'GET',
		headers: {
		  'Content-Type': 'application/x-www-form-urlencoded',
		  'Cookie':'cad=mXbaBQX0A0BZYtYBpbsc5g==; cap=83fa; cn_ea1523f470091651998a_dplus=%7B%22distinct_id%22%3A%20%2214e75a31854728-0559ec46d-1e533e45-100200-14e75a318636abc%22%7D; cn_c715dc981aabb45190b2_alifenxi=%7B%22distinct_id%22%3A%20%2214ddc7a3d60422-0c7b86d7c-1e533e45-100200-14ddc7a3d70142d%22%2C%22%24initial_time%22%3A%201433894359%2C%22%24initial_referrer%22%3A%20%22http%3A%2F%2Ftongji.cnzz.com%2Fmain.php%3Fc%3Dsite%26a%3Dshow%26from%3Dlogin%22%2C%22%24initial_referring_domain%22%3A%20%22tongji.cnzz.com%22%7D; UC_SID=6aac0ba7e4a21956631f9bb884ab36b2; cn_session_id_ea1523f470091651998a=1439287306; isg=FCADD15EF8CF8F470E9B08617499EBB3; l=AqWlkiVEDpv5Yi34FzoERZEdNW/f-1l0; PHPSESSID=rf9oo785ppcqbm44j1jror6rs3; cn_ea1523f470091651998a_alifenxi=%7B%22distinct_id%22%3A%20%2214e95d8a95334e-0e238be25-1e533e45-100200-14e95d8a9631802%22%2C%22%24initial_time%22%3A%201437004306%2C%22%24initial_referrer%22%3A%20%22https%3A%2F%2Fi.cnzz.com%2Fmain.php%3Fc%3Duseropt%26a%3Dlogin%26style%3D1%26ptype%3D2%26tab%3D20%26rurl%3Dhttp%253A%252F%252Ftongji.cnzz.com%252Fmain.php%253Fc%253Dsite%2526a%253Dshow%2526from%253Dlogin%22%2C%22%24initial_referring_domain%22%3A%20%22i.cnzz.com%22%2C%22%24recent_outside_referrer%22%3A%20%22%24same%22%7D; frontvar=siteShowHis%3Dopen%26cmenu%3D0%26siteListSortId%3D%26siteOverviewFlowLineTime%3D1%26districtnetInfo%3Dcity%26lns%3Dmenu-1%2Cflow-1%2Ctraf-1%2Ccont-1%2Cvisitor-1%2Cbigdata-1%2Cindustry-1%2Ceanalysis-1%2C; cn_c715dc981aabb45190b2_cnzzneedle=%7B%22distinct_id%22%3A%20%2214e95d8a0eb7c9-0ffac2bae-1e533e45-100200-14e95d8a0fa1614%22%7D; CNZZDATA30086426=cnzz_eid%3D1802116903-1433919811-null%26ntime%3D1439285038; CNZZDATA30069868=cnzz_eid%3D1377382592-1433919248-null%26ntime%3D1439285506; _cnzz_CV30069868=%E6%98%AF%E5%90%A6%E7%99%BB%E5%BD%95%7C%E6%AD%A3%E5%B8%B8%E7%99%BB%E5%BD%95%7C1439316723919; CNZZDATA33222=cnzz_eid%3D1788284253-1433919024-null%26ntime%3D1439284668; CNZZDATA30001831=cnzz_eid%3D1043008422-1433922753-null%26ntime%3D1439287864; cna=u7/+DeGaBjoCAWJ+IQrG01Hw',
		  'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36 QIHU 360SE'     
		}
	};

	var request = http.request(options,function(res){
	  res.setEncoding('utf8');
	  var content = ''
	  res.on('data', function (chunk) {
	  	content+=chunk;
	  });
	  res.on('end',function(){
	  	try{
	    	var data = JSON.parse(content).data;
	    	var items = data.summary.items;
	    	// 返回昨天的cnzz统计
	    	callback(items,setting);
	  	}catch(err){
	  		console.log(err);
	  	}	
	  });
	});
	request.end();	
};	

// 上传数据
function uploadData(cnzzData,setting,callback){
	var data = cnzzData;
	if(data){
		var pv = parseInt(data.pv)
			,field = setting.field
			,title = setting.title
			,cnzzid = setting.cnzzid
			,maxpv = setting.maxpv
			,cpm = setting.cpm
			,minAvailPer = setting.minAvailPer
			,minPercent = setting.minPercent
			,maxPercent = setting.maxPercent
			;
		if(maxpv==-1){	// 如果每天投放流量不固定，数据以cnzz为准
			maxpv = pv;
			minAvailPer = 1;
		}	
		if(maxpv>=pv&&(pv/maxpv)>=minAvailPer){ // maxpv必须大于cnzz统计s
			// 生成数据
			var request = parseInt(maxpv*(minPercent+(maxPercent-minPercent)*Math.random()))
				,view = parseInt(request*(1-Math.random()*0.15))
				,revenue = (cpm*request/1000).toFixed(2)
				,yesterday = new Date(Date.now()-24*60*60*1000)
				,m = yesterday.getMonth()+1
				,d = yesterday.getDate()
				,yesterday_str = yesterday.getFullYear()+'-'+(m<10?'0'+m:m)+'-'+(d<10?'0'+d:d)
				;
			// 报表数据
			var reportData = {
				title:title,
				date:yesterday_str,
				request:request,
				view:view,
				click:0,
				revenue:revenue											
			};
			deliverManagement.addReportData(field,new Date(yesterday.toDateString()).getTime(),reportData,function(err,reply){
				if(err){
					callback&&callback(err)
				}else{
					callback&&callback(null,reply)
				}
			});									
		}else{
			console.log('数据异常',pv,maxpv,(pv/maxpv).toFixed(2))
			callback&&callback('数据异常，无法生成数据')
		}								
	}else{
		callback&&callback('无法获取cnzz数据')
	}
};

var deliverManagement = {
	initDeliverID : function(){
		client.setnx(redisKey.getDeliverIdKey(), 1);
	},	
	//save deliver
	createDeliver: function(obj, callback) {
		if(obj&&typeof obj=='object'){	
			var sid=obj.sid;
			client.get(redisKey.getDeliverIdKey(), function(err, reply){
				if(reply){
					obj.field = sid + ':' + reply;
					client.hset(redisKey.getDeliverKey(), obj.field, JSON.stringify(obj), function(err, result){
						if(err){
							callback({err:'广告创建失败:增加广告失败'});
						}else{
							client.lpush(redisKey.getDeliverListKey(sid), sid + ':' + reply, function(err, reply){
								if(reply){
									client.incr(redisKey.getDeliverIdKey(), function(err, reply){
										if(reply){
											callback({success:true});
										}else{
											callback({err:'广告创建失败'});
										}
									});
								}else{
									callback({err:'广告创建失败:增加广告列表失败'});
								}
							});	
						}
					});	
				}else{
					callback({err:'获取广告id失败'});
				}
			});
		}else{
			callback({err:'广告创建失败'});
		}
	},
	//edit deliver
	editDeliver: function (obj, callback) {
		if(obj&&typeof obj=='object'){
			client.hget(redisKey.getDeliverKey(), obj.field, function(err, reply){
				if(reply){									
					var deleverObj = JSON.parse(reply),
						author = obj.author;
					delete obj.author;	//delete author attribute
					obj.siteField = deleverObj.siteField;
					obj.widgetType = deleverObj.widgetType;
					obj.field = deleverObj.field;
					obj.sid = deleverObj.sid;													
									
					client.hset(redisKey.getDeliverKey(), obj.field, JSON.stringify(obj), function(err, result){
						if(err){
							callback({err:'广告更新失败'});
						}else{
							widget.widgetDetail(obj.siteField,function(result){								
								if(result){
									var w = JSON.parse(result);
									getDiff(deleverObj,obj).forEach(function(val,index){	//keep change log
										var changeObj = {
											siteField : deleverObj.siteField,											
											widgetField : deleverObj.field,
											domain : w.domain,
											author : author,
											type : 'update',
											column : val.column,
											oldValue : val.oldValue,
											newValue : val.newValue
										};
										changeLog.add(changeObj);
									});
								}
							});
							callback({
								success : true,				
							});
						}
					});
	
				}else{
					callback({err:'广告不存在'});
				}
			});
		}else{
			callback({err:'广告数据不能为空'});
		}
	},
	//delete deliver,just get rid of the record from deliverlist
	delDeliver: function(field, author,callback){
		var sid = field.split(':')[0];
		client.lrem(redisKey.getDeliverListKey(sid), 1, field, function(err, res){
			if(1 <= res){
				client.hget(redisKey.getDeliverKey(),field,function(err,reply){	//keep change log
					if(reply){
						var d = JSON.parse(reply);
						widget.widgetDetail(d.siteField,function(result){							
							var w = JSON.parse(result);
							if(result){
								var changeObj = {
									siteField : d.siteField,							
									widgetField : field,
									domain : w.domain,									
									author : author,
									type : 'delete',
									column : '',
									oldValue : '',
									newValue : ''
								};
								changeLog.add(changeObj);
							}

						});
					}
				})
				callback({success:true});
			}else{
				callback({err:'删除错误或者不存在该广告'});
			}
		});
	},
	//active deliver
	activeDeliver: function(field, callback){
		client.hget(redisKey.getDeliverKey(), field, function(err, reply){
			if(reply){
				var obj = JSON.parse(reply);
				obj.isAlive = 1;
				client.hset(redisKey.getDeliverKey(), field, JSON.stringify(obj), function(err, res){
					if(err){
						callback({err:'激活广告失败'});
					}else{
						callback({success:true});
					}
				});
			}else{
				callback({err:'未找到该广告'});
			}
		});
	},
	//stop deliver
	stopDeliver: function(field, callback){
		client.hget(redisKey.getDeliverKey(), field, function(err, reply){
			if(reply){
				var obj = JSON.parse(reply);
				obj.isAlive = 0;
				client.hset(redisKey.getDeliverKey(), field, JSON.stringify(obj), function(err, res){
					if(err){
						callback({err:'暂停广告失败'});
					}else{
						callback({success:true});
					}
				});
			}else{
				callback({err:'未找到该广告'});
			}
		});
	},
	//get sum of delivers
	getDeliverCount : function(sid, callback){
		client.llen(redisKey.getDeliverListKey(sid),function(err,reply){			
			callback(reply);
		});
	},
	//get deliver list 
	listDelivers :function(sid, start, end, callback){
		client.lrange(redisKey.getDeliverListKey(sid), start, end, function(err,replies) {
			if(err){
				callback({err:err});
			}else{				
				var sid_arr=replies;				
				var multi=client.multi();	
				if(sid_arr.length>0){
					for(var i=0,len=sid_arr.length;i<len;i++){
						var sid=sid_arr[i];
						multi.hget(redisKey.getDeliverKey(),sid);
					}		
					multi.exec(function(err,replies){
						if(err){
							callback({err:err});
						}else{
							callback(replies);
						}
					});	
				}else{
					callback({err:'widget list is empty'});
				}
			}
		});
	},
	//get deliver detail
	//field: 'sid:id'
	deliverDetail: function (field, callback){
		client.hget(redisKey.getDeliverKey(), field, function(err,reply) {
			if(reply){
				callback(reply);
			}else{
				callback(0);
			}
		});
	},
	// 添加广告数据
	addReportData: function(field,timestamp,data,callback){
		var key = redisKey.getReportKey(field);
		client.hset(key,timestamp,JSON.stringify(data),function(err,reply){
			if(err){
				callback(err);
			}else{
				callback(null,reply);
			}
		})
	},
	// 查询广告数据
	getReportData: function(field,dateArr,callback){
		var key = redisKey.getReportKey(field);
		client.hmget(key,dateArr,function(err,reply){
			if(err){
				callback(err)
			}else{
				callback(null,reply);
			}
		})
	},
	// 保存报表设置
	setReportSetting: function(field,data,callback){
		var key = redisKey.getWidgetReportKey();
		client.hset(key,field,JSON.stringify(data),function(err,reply){
			if(err){
				callback(err)
			}else{
				callback(null,reply)
			}
		})
	},
	// 获取报表设置
	getReportSetting: function(field,callback){
		var key = redisKey.getWidgetReportKey();
		client.hget(key,field,function(err,reply){
			if(err){
				callback(err)
			}else{
				callback(null,reply)
			}
		})
	},
	// 定时生成凤凰数据
	generateReportData: function(callback){
		var CronJob = require('cron').CronJob;	
		// 设置定时任务，每天8:00:00执行
		var job = new CronJob('00 00 08 * * *', function() {
			var key = redisKey.getWidgetReportKey();
			client.hgetall(key,function(err,reply){
				if(err){
					callback(err)
				}else{
					var widgetList = reply;
					for(var i in widgetList){
						if(i.length){	// 判断property是否为字符串
							var field = i
								,setting = JSON.parse(widgetList[field])
								;
							getCnzzData(setting,function(data,setting){
								uploadData(data,setting);
							});
						}
					}
				}
			});
		  }, 
		  null,
		  true, /* Start the job right now */
		  ''
		);	
	},
	// 生成单个广告插件报表
	generateSingleReportData: function(field,callback){
		var key = redisKey.getWidgetReportKey();
		if(field){
			client.hget(key,field,function(err,reply){
				if(err){
					callback(err)
				}else{
					var setting = JSON.parse(reply);
					getCnzzData(setting,function(data,setting){
						uploadData(data,setting,callback)
					})
				}
			})
		}else{
			callback('field is needed');
		}
	}

}

module.exports = deliverManagement;